
#include "imtPublic.h"
#include "imtAction.h"
#include "imtActionManager.h"

namespace iMate {

	bool IAction::enter()
	{
		bool ret = this->onEnter();
		if (mDecoratee)
		{
			ret = mDecoratee->enter() && ret;
		}
		if (ret)
		{
			mActionState = AS_Entered;
		}
		return ret;
	}

	bool IAction::activate()
	{
		bool ret = this->onActive();
		if (mDecoratee)
		{
			ret = mDecoratee->activate() && ret;
		}
		if (ret)
		{
			mActionState = AS_Active;
		}
		return ret;
	}

	void IAction::run(Real timeElapsed)
	{
		this->onRun(timeElapsed);
		if (mDecoratee)
		{
			mDecoratee->run(timeElapsed);
		}
	}

	bool IAction::stop()
	{
		bool ret = this->onStop();
		if (mDecoratee)
		{
			ret = mDecoratee->stop() && ret;
		}
		mManualEnd = ret;

		return ret;
	}

	void IAction::terminate()
	{
		this->onTerminate();
		if (mDecoratee)
		{
			mDecoratee->terminate();
		}
		mActionState = (mActionState == AS_Success ? AS_Success : AS_Failed);
	}

	ActionState IAction::getActionState() const
	{
		if (mDecoratee && mActionState > mDecoratee->getActionState())
		{
			return mDecoratee->getActionState();
		}
		return mActionState;
	}

	bool IAction::isOver() const 
	{
		return AS_Success == getActionState()
			&& (!mDecoratee || mDecoratee->isOver());
	}

	IAction* IAction::decorate(IAction* decorater)
	{
		if (!decorater) return 0;

		if (mDecoratee)
			mDecoratee->decorate(decorater);
		else
			mDecoratee = decorater;

		return this;
	}
	void IAction::clearDecoratee()
	{
		if (mDecoratee)
		{
			ActionManager::getSingleton().destroyAction(mDecoratee);
			mDecoratee = 0;
		}
	}
	IAction* IAction::getDecorate(uint index /*= 0*/)
	{
		uint i = 0;
		IAction* decorater = mDecoratee;
		while( decorater && ( i < index ) )
		{
			++i;
			decorater = decorater->getDecorate(0);
		}
		return decorater;
	}

	bool IAction::hasAction(const IAction* action) const
	{
		return (action == this) 
			|| (mDecoratee && mDecoratee->hasAction(action));
	}

}//iMate